package com.usian.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.usian.admin.feign.ArticleFeign;
import com.usian.admin.feign.WemediaFeign;
import com.usian.admin.service.AdChannelService;
import com.usian.admin.service.AdSensitiveService;
import com.usian.admin.service.WemediaNewsAutoScanService;
import com.usian.common.aliyun.util.GreenImageScan;
import com.usian.common.aliyun.util.GreenTextScan;
import com.usian.common.fastdfs.FastDFSClientUtil;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.admin.pojos.AdChannel;
import com.usian.model.admin.pojos.AdSensitive;
import com.usian.model.article.pojos.ApArticle;
import com.usian.model.article.pojos.ApArticleConfig;
import com.usian.model.article.pojos.ApArticleContent;
import com.usian.model.article.pojos.ApAuthor;
import com.usian.model.common.dtos.PageResponseResult;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsVo;
import com.usian.utils.common.SensitiveWordUtil;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    @Autowired
    private WemediaFeign wemediaFeign;
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    private AdChannelService adChannelService;
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private FastDFSClientUtil fastDFSClientUtil;
    @Value("${fileServerUrl}")
    private String fileServerUrl;
    @Autowired
    private AdSensitiveService adSensitiveService;


    @GlobalTransactional
    public void newsAutoScan(Integer id) {

        //1: 校验参数，获取要审核的文章对象
        if (id == null) {
            return;
        }
        WmNews wmNews = wemediaFeign.findByNewsId(id);
        if (wmNews == null) {
            return;
        }

        Long articleId=null;

        //2: 根据文章不同的状态决定是否要审核
        if (wmNews.getStatus() == 4) {
            //4：人工审核通过
            articleId = this.saveArticle(wmNews);
        }
        if (wmNews.getStatus() == 8 && wmNews.getPublishTime().getTime() <= System.currentTimeMillis()) {
            //157323232323323    154545454545454543
            articleId = this.saveArticle(wmNews);
        }

        //3: 审核  阿里云内容安全接口（test  image） 敏感词
        if (wmNews.getStatus() == 1) {

            //审核文本 --阿里云
            Map<String, Object> map = this.handleTextAndImages(wmNews);
            String textStr = (String) map.get("content");
            boolean textScan = this.handleTextScan(textStr, wmNews);
            if (!textScan) {
                return;
            }

            //审核图片 - 阿里云
            List<String> imageList = (List<String>)map.get("images");
            boolean imagesScan = this.handleImagesScan(imageList, wmNews);
            if(!imagesScan){
                return;
            }

            //审核敏感词
            boolean handleSensitive = this.handleSensitive(textStr, wmNews);
            if(!handleSensitive){
                return;
            }
            //5: wmnews -->  ap_article   ap_article_content  ap_article_config
            articleId = this.saveArticle(wmNews);
        }


        //4: 修改wmnews status 8 / 9
        wmNews.setArticleId(articleId);
        if(wmNews.getPublishTime().getTime()>System.currentTimeMillis()){
            this.updateWmnewStatus(wmNews,(short)8,"审核通过，待发布");
        }else{
            this.updateWmnewStatus(wmNews,(short)9,"审核通过，已发布");
        }

    }


    private boolean handleSensitive(String content,WmNews wmNews){
        boolean flag =false;
        List<AdSensitive> sensitiveList = adSensitiveService.findAllSensitive();

        List<String> sensitiveListStr =new ArrayList<>();
        for(AdSensitive adSensitive :sensitiveList){
            sensitiveListStr.add(adSensitive.getSensitives());
        }
        SensitiveWordUtil.initMap(sensitiveListStr);

        Map<String, Integer> words = SensitiveWordUtil.matchWords(content);
        if(words.size()==0){
            //包含敏感词，审核通过
            flag =true;
        }else{
            //不通过
            this.updateWmnewStatus(wmNews,(short)2,"内容中包含敏感词");
        }
        return flag;
    }

    private Map<String,Object> handleTextAndImages(WmNews wmNews){
        String content = wmNews.getContent();

        StringBuilder stringBuilder =new StringBuilder();
        List<String> imageList =new ArrayList<>();

        List<Map> list = JSON.parseArray(content, Map.class);
        //分离内容图片
        for(Map map:list){
            if(map.get("type").equals("text")){
                stringBuilder.append(map.get("value"));
            }
            if(map.get("type").equals("image")){
                imageList.add(map.get("value").toString());
            }
        }
        //分离封面图片
        if(wmNews.getImages()!=null && wmNews.getType()>0){
            String[] strings = wmNews.getImages().split(",");
            imageList.addAll(Arrays.asList(strings));
        }

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("content", stringBuilder.toString());
        resultMap.put("images", imageList);
        return resultMap;
    }

    private boolean handleImagesScan(List<String> images, WmNews wmNews) {
        if (images == null) {
            return true;
        }
        boolean flag = false;

        try {
            List<byte[]> imageList = new ArrayList<>();
            for (String image : images) {
                //http://192.168.58.153/group1/M00/1/2/111.jpg
                String replace = image.replace(fileServerUrl, "");
                //group1/M00/1/2/111.jpg
                String groupName = replace.substring(0, replace.indexOf("/"));
                String groupPath = replace.substring(replace.indexOf("/") + 1);
                byte[] bytes = fastDFSClientUtil.download(groupName, groupPath);
                imageList.add(bytes);
            }

            Map map = greenImageScan.imageScan(imageList);
            if (!map.get("suggestion").equals("pass")) {
                // block  review
                if (map.get("suggestion").equals("block")) {
                    this.updateWmnewStatus(wmNews, (short) 2, "图片审核不通过");
                }
                if (map.get("suggestion").equals("review")) {
                    this.updateWmnewStatus(wmNews, (short) 3, "图片审核不确定，建议人工审核");
                }
            } else {
                flag = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    public boolean handleTextScan(String content, WmNews wmNews) {
        boolean flag = false;
        try {
            Map map = greenTextScan.greeTextScan(content);
            if (!map.get("suggestion").equals("pass")) {
                // block  review
                if (map.get("suggestion").equals("block")) {
                    this.updateWmnewStatus(wmNews, (short) 2, "文本审核不通过");
                }
                if (map.get("suggestion").equals("review")) {
                    this.updateWmnewStatus(wmNews, (short) 3, "文本审核不确定，建议人工审核");
                }
            } else {
                flag = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    private void updateWmnewStatus(WmNews wmNews, Short status, String msg) {
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        wemediaFeign.updateNewStatus(wmNews);
    }

    private Long saveArticle(WmNews wmNews) {
        //ap_article   ap_article_content  ap_article_config
        ApArticle apArticle = new ApArticle();
        apArticle.setTitle(wmNews.getTitle());
        apArticle.setLayout(wmNews.getType());
        apArticle.setImages(wmNews.getImages());
        apArticle.setCreatedTime(new Date());

        Integer userId = wmNews.getUserId();
        ApAuthor apAuthor = articleFeign.findByWmUserId(userId);
        if (apAuthor != null) {
            apArticle.setAuthorId(Long.valueOf(apAuthor.getId()));
            apArticle.setAuthorName(apAuthor.getName());
        }

        Integer channelId = wmNews.getChannelId();
        AdChannel adChannel = adChannelService.getById(channelId);
        if (adChannel != null) {
            apArticle.setChannelId(channelId);
            apArticle.setChannelName(adChannel.getName());
        }
        ApArticle apArticle1 = articleFeign.saveApArticle(apArticle);

        //2
        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(apArticle1.getId());
        apArticleContent.setContent(wmNews.getContent());
        ApArticleContent apArticleContent1 = articleFeign.saveApArticleContent(apArticleContent);

        //3:
        ApArticleConfig apArticleConfig = new ApArticleConfig();
        apArticleConfig.setArticleId(apArticle1.getId());
        apArticleConfig.setIsForward(true);
        apArticleConfig.setIsDelete(false);
        apArticleConfig.setIsDown(true);
        apArticleConfig.setIsComment(true);
        ApArticleConfig apArticleConfig1 = articleFeign.saveApArticleConfig(apArticleConfig);

        return apArticle1.getId();
    }


    @Override
    public ResponseResult findNews(NewsAuthDto dto) {

        ResponseResult list = wemediaFeign.findList(dto);
        list.setHost(fileServerUrl);

        return list;
    }

    @Override
    public ResponseResult findNewsById(Integer id) {
        if(id==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNewsVo wmNewsVo = wemediaFeign.findNewsById(id);
        return ResponseResult.okResult(wmNewsVo);
    }

    @Override
    public ResponseResult authPass(NewsAuthDto dto) {
        if(dto==null && dto.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        WmNews wmNews = wemediaFeign.findByNewsId(dto.getId());
        this.updateWmnewStatus(wmNews,(short)4,"人工审核通过");
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult authFail(NewsAuthDto dto) {
        if(dto==null && dto.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        WmNews wmNews = wemediaFeign.findByNewsId(dto.getId());
        this.updateWmnewStatus(wmNews,(short)2,"人工审核失败");
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

}
